package com.ruoyi.web.controller.pack;

import com.ruoyi.common.annotation.Anonymous;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.config.YuntianxiaConfig;
import com.ruoyi.common.utils.SignatureUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 云天下API绑定Controller
 *
 * @author ruoyi
 * @date 2024-01-01
 */
@Api(tags = "云天下API绑定")
@RestController
@RequestMapping("/yuntianxia")
public class YuntianxiaApiController {

    private static final Logger logger = LoggerFactory.getLogger(YuntianxiaApiController.class);

    @Autowired
    private YuntianxiaConfig yuntianxiaConfig;

    /**
     * URL&Token 验证接口
     * 功能说明：URL&Token 验证接口。如果验证成功返回 nonce 的值,否则返回其他值。
     *
     * @param nonce 随机串
     * @param signature 签名
     * @param timestamp 时间戳
     * @return 验证成功返回 nonce,失败返回 error
     */
    @RequestMapping(value = "/receive", method = RequestMethod.GET)
    @ResponseBody
    @Anonymous
    @ApiOperation("URL&Token验证接口")
    public String check(
            @ApiParam(value = "随机串", required = false) @RequestParam(value = "nonce") String nonce,
            @ApiParam(value = "签名", required = false) @RequestParam(value = "signature") String signature,
            @ApiParam(value = "时间戳", required = false) @RequestParam(value = "timestamp") String timestamp) {

        logger.info("url&token check: nonce={}, signature={}, timestamp={}", nonce, signature, timestamp);

        // 获取配置的token
        String token = yuntianxiaConfig.getToken();

        // 验证签名
        if (SignatureUtils.checkSignature(signature, timestamp, nonce, token)) {
            logger.info("云天下API签名验证成功，返回nonce: {}", nonce);
            return nonce;
        } else {
            logger.warn("云天下API签名验证失败，signature={}, timestamp={}, nonce={}", signature, timestamp, nonce);
            return "error";
        }
    }

    /**
     * 生成签名接口
     *
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return 生成的签名
     */
    @RequestMapping(value = "/generateSignature", method = RequestMethod.GET)
    @ResponseBody
    @Anonymous
    @ApiOperation("生成签名接口")
    public String generateSignature(
            @ApiParam(value = "时间戳", required = true) @RequestParam(value = "timestamp") String timestamp,
            @ApiParam(value = "随机数", required = true) @RequestParam(value = "nonce") String nonce) {

        logger.info("生成签名: timestamp={}, nonce={}", timestamp, nonce);

        // 获取配置的token
        String token = yuntianxiaConfig.getToken();

        // 生成签名
        String signature = generateSignature(timestamp, nonce, token);

        logger.info("生成签名成功: signature={}", signature);
        return signature;
    }

    /**
     * 生成签名
     *
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @param token token
     * @return 签名
     */
    private String generateSignature(String timestamp, String nonce, String token) {
        // 1. 将token、timestamp、nonce三个参数进行字典序排序
        String[] array = {token, timestamp, nonce};
        java.util.Arrays.sort(array);

        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder content = new StringBuilder();
        for (String item : array) {
            content.append(item);
        }

        // 3. 使用SHA1算法加密
        return sha1(content.toString());
    }

    /**
     * SHA1加密
     *
     * @param str 待加密字符串
     * @return 加密后的字符串
     */
    private String sha1(String str) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(str.getBytes());
            return byteArrayToHexString(digest);
        } catch (java.security.NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA1加密失败", e);
        }
    }

    /**
     * 字节数组转十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private String byteArrayToHexString(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(SignatureUtils.byteToHexStr(b));
        }
        return result.toString();
    }

    /**
     * 获取配置信息接口
     *
     * @return 配置信息
     */
    @RequestMapping(value = "/config", method = RequestMethod.GET)
    @ResponseBody
    @Anonymous
    @ApiOperation("获取配置信息")
    public Object getConfig() {
        return new Object() {
            public String getToken() { return yuntianxiaConfig.getToken(); }
            public String getApiUrl() { return yuntianxiaConfig.getApiUrl(); }
            public boolean isEnabled() { return yuntianxiaConfig.isEnabled(); }
        };
    }
}
